#include <iostream>
using namespace std;

class Point
{
public:
    // 使用带参数默认构造函数，并使用初始化列表初始化 x，y
    Point(double x = 0, double y = 0) : x(x), y(y) {
        //cout << "Point(double x = 0, double y = 0)" << endl;
        cout << "Point(double x = " << x << ", double y = " << y << ")" << endl;
    }
    // 拷贝构造函数
    Point(const Point & p) {
        //cout << "Point(const Point &p)" << endl;
        // 打印点的值
        cout << "Point(const Point &p:(" << p.x << ", " << p.y << ")" << endl;
        this->x = p.x;
        this->y = p.y;
    }
    // 析构函数，由于没有申请内存，析构函数中不需要做什么
    ~Point() {
        //cout << "~Point()" << endl;
        cout << "~Point():(" << x << ", " << y << ")" << endl;
    }
    // x, y 绑定的成成员函数
    void setPoint(const Point &p) {
        this->x = p.x;
        this->y = p.y;
    }
    void setPoint(double x, double y) {
        this->x = x;
        this->y = y;
    }
    void setX(double x) { this->x = x; }
    void setY(double y) { this->y = y; }
    double getX() { return x; }
    double getY() { return y; }
private:
    double x;
    double y;
};

class Line
{
public:
    Line(const Point & pA, const Point &pB) : pointA(new Point(pA)), pointB(new Point(pB)) {
        cout << "Line(const Point & pA, const Point &pB)" << endl;
    }
    Line(double aX, double aY, double bX, double bY) : pointA(new Point(aX, aY)), pointB(new Point(bX, bY)) {
        cout << "Line(double aX, double aY, double bX, double bY)" << endl;
    }
    Line(const Line& line) {
        cout << "Line(const Line& line)" << endl;
        // 浅拷贝
        // pointA = line.pointA;
        // pointB = line.pointB;

        // 深拷贝
        pointA = new Point;
        pointB = new Point;
        pointA->setPoint(*line.pointA);
        pointB->setPoint(*line.pointB);
    }
    Line(Line* line) {
        cout << "Line(Line* line)" << endl;
        pointA = new Point;
        pointB = new Point;
        pointA->setPoint(*line->pointA);
        pointB->setPoint(*line->pointB);
    }
    ~Line() {
        cout << "~Line()" << endl;
        delete pointA;
        pointA = nullptr;
        delete pointB;
        pointB = nullptr;
    }
private:
    Point *pointA;
    Point *pointB;
};

int main()
{
    Line *p = new Line(1, 2, 3, 4);

    cout << "sizeof(Line) = " << sizeof(Line) << endl;

    /**
     * 使用场景
     * 1. 使用拷贝构造
     * 2. 赋值运算符
     * 
     * 注意事项：
     * 1. 当我们不写拷贝构造函数时，系统自动生成拷贝构造函数，而且是浅拷贝
     * 2. 在编写拷贝构造时需要考虑多种调用场景
    */
    Line *p2 = new Line(*p);
    Line *p3 = new Line(p);

    delete p;
    p = nullptr;
    delete p2;
    p2 = nullptr;
    delete p3;
    p3 = nullptr;

    return 0;
}